package com.manulife.hk.performance.services;

import com.manulife.hk.performance.domains.IssueSaleEntity;
import com.manulife.hk.performance.repository.IssueSaleRepository;

import org.apache.commons.collections.IteratorUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;

import javax.persistence.EntityNotFoundException;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

@Service
public class IssueSaleServiceImpl implements IssueSaleService{

    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private IssueSaleRepository issueSaleRepository;

    @SuppressWarnings("unchecked")
	@Override
    public List<IssueSaleEntity> addList(List<IssueSaleEntity> issueSales) {
    	Iterable<IssueSaleEntity> resultList = issueSaleRepository.save(issueSales);
    	return IteratorUtils.toList(resultList.iterator());
    }

    @Override
    public void remove(Long id) {
    	IssueSaleEntity entity = issueSaleRepository.findOne(id);
    	if(null == entity) {
    		throw new EntityNotFoundException("IssueSale record not found: id="+id);
    	}
    	log.info("IssueSale record to be deleted: {}", entity.toString());
        issueSaleRepository.delete(id);
    }

    @Override
    public List<IssueSaleEntity> findAll(IssueSaleEntity issueSale) {
        return issueSaleRepository.findAll(new Specification<IssueSaleEntity>() {
            @Override
            public Predicate toPredicate(Root<IssueSaleEntity> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> list = getQueryCondition(issueSale, root, cb);
                Predicate[] p = new Predicate[list.size()];
                return cb.and(list.toArray(p));
            }
        });
    }

    private List<Predicate> getQueryCondition(IssueSaleEntity issueSale, Root<IssueSaleEntity> root, CriteriaBuilder cb) {

        List<Predicate> list = new ArrayList<>();

        if (StringUtils.isNotBlank(issueSale.getAgentCode())) {
            list.add(cb.equal(root.get("agentCode").as(String.class), issueSale.getAgentCode()));
        }
        if (StringUtils.isNotBlank(issueSale.getContractNum())) {
            list.add(cb.equal(root.get("contractNum").as(String.class), issueSale.getContractNum()));
        }

        return list;
    }
}
